/** File Description
 *
 * Copyright (C) 2009 Ismail SEZEN
 * Windbull (Wind statistical analyser)
 * -------------------------------------------------------------------------------------------
 * This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * -------------------------------------------------------------------------------------------
 * Project Name: Windbull
 * Files(4) : Windbull.c, Windbull.h, WindbullParser.c, WindbullParser.h
 * AUTHOR: Ismail SEZEN
 * e-mail: sezenismail@gmail.com
 * 13-05-2009 [12:20]
 * -------------------------------------------------------------------------------------------
 * Created by Code:Blocks 8.02
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h>
#include <fcntl.h>
#include <unistd.h>
//My Header files
#include "src/Windbull.h"
//
#define LINES 730
#define BUFSIZE 160

#define YEAR 1995
#define MONTH 12
#define DAY 31
#define HOUR 24
#define TOTALDATACOUNT (HOUR*LINES)

/**Defines the length of an array*/
//#define length(a) (sizeof a / sizeof a[0])

///Method prototypes
void wind_calculation();
//ParseHelper.c
//int parse_data_1D_2array(char *pData,int buffer_size,int line_count, float *raw_speed_array,int *raw_direction_array,int col_count);
//Bottom routines in this file
//int read_file_to_array(char *fileName, char *parr, int *line_count,int buff_size);

char data[LINES][BUFSIZ];
//
float f_raw_speed_1D[TOTALDATACOUNT];
//
int raw_speeed_1D[TOTALDATACOUNT];
int raw_direction_1D[TOTALDATACOUNT];
//
int raw_speed_2D[LINES][HOUR];
int raw_direction_2D[LINES][HOUR];
//
float rare_speed[YEAR][MONTH][DAY][HOUR];
int rare_direction[YEAR][MONTH][DAY][HOUR];


/**Program Main Entry Point */
int main(int argc, char *argv[]) {
//    int i;
//    printf("argc = %d\n", argc);
//    for (i = 0; i < argc; i++)
//	printf("argv[%d] = \"%s\"\n", i, argv[i]);

	printf("Windbull  Copyright (C) 2009  Ismail SEZEN\nThis program comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome to redistribute it.\nunder certain conditions.\n");

	if(argc < 2){
		printf("You have to supply a filename.\nUSAGE : ./program_name filename [output_filename]\n");
		return 1;
	}
	//int line_count = 0;
	char *fileName = argv[1];
	char *outFileName;
	FILE *FD = NULL;
	if(argc == 3){
		outFileName = argv[2];
		FD = freopen (outFileName,"w",stdout);
        	if ( FD == NULL ) printf("Error on opening output file! Falling back to screen mode\n");
	}
	printf("FileName = %s\n",fileName);
	//
	if( WB_Initialize(fileName) == 0 ){
		WB_z0 = 0.05f;//0.5m. forAkcakoca
		WB_height = 10.0f; /*We will calculate the results for 10m. height.*/
		/*Basic statistical data Calculations*/
		//----------------------------------------------------------------------------------------------------------------------------------------------------------------------
		float max = WB_speed_max();
		float min = WB_speed_min();
		float avg = WB_speed_avg();
		float  median = WB_speed_median();
		float mode = WB_speed_mode();
		double sd = WB_speed_sd();
		double v = WB_speed_variance();
		double lam_per = WB_lambert_persistance();
		//Autocorrelation
		//double acc = autocorelation(&f_raw_speed_1D[0],total_data_count,1);
		double acc = WB_autocorrelation();
		//
		printf("Basic statistical data:\n");
		printf("Max Speed\tMin Speed\tAvg.Speed\tMedian\tMode\tStd.Dev.\tVariance\tAcc\t\tLambert\n");
		printf("---------\t---------\t---------\t------\t-----\t--------\t--------\t---\t\t-------\n");
		printf("%g\t\t%g\t\t%g\t\t%g\t%g\t%g\t\t%g\t\t%g\t%g\n\n",max,min,avg,median,mode,sd,v,acc,lam_per);


		double* sd_hourly_arr = WB_sd_hourly();
		printf("\n");
		double* var_hourly_arr = WB_variance_hourly();
		register int i;
//		for(i=0;i<24;i++) printf("%g\n",sd_hourly_arr[i]);
//		printf("\n");
//		for(i=0;i<24;i++) printf("%g\n",var_hourly_arr[i]);


		/*Calculates and printds the lambert equation results*/
		printf("\n");

		int direction_freq[17];
		WB_direction_frequencies(&direction_freq[0]);
		double speed_freq[17];
		WB_speed_frequencies(&speed_freq[0]);

		printf("Directions:\t\t");
		for(i=0;i<=16;i++) printf("%d(%s)\t",i,WB_Direction_to_string[i]);
		printf("\n");
		printf("-------------------\t");
		for(i=0;i<=16;i++) printf("------\t");
		printf("\nNumber of Blowings:\t");
		int total = 0;
		for(i=0;i<=16;i++){
			total+=direction_freq[i];
			printf("%d\t",direction_freq[i]);
		}
		printf("\n");
		printf("Percent. of Blowings:\t");
		for(i=0;i<=16;i++){
			printf("%.4f\t",((double)direction_freq[i]/(double)total)*100);
		}
		printf("\n");
		printf("speed due to Direc.:\t");
		for(i=0;i<=16;i++){
			printf("%.4f\t",speed_freq[i]);
		}

		printf("\n");
		printf("Total defined directions count = %d\n",total);
		printf("\n");
		WB_speed_histogram();
		//Print results
//		printf("\nBin value = %g\n",WB_bin);
//		printf("Class count = %d\n",w);
//		printf("i\tinterval\t\t\tui\t\tmi\tp(ui)\t\tF(ui)\n");
//		printf("----------------------------------------------------------------------------------------------\n");
//		for(i=0;i<w;i++){
//			printf("%d\t%e-%e\t%e\t%d\t%e\t%e\n",i,(i * bin),((i+1)*bin),(*(p_ui+i)),*(p_mi+i),*(p_pui+i),*(p_Fui+i));
//		}
		//
		printf("\n");
		/*Energy pattern factor*/
		double Ke = WB_energy_pattern_factor();
		printf("Energy Pattern Factor = %g\n",Ke);

		double k = WB_weibull_k_param();
		printf("Weibull k param %f\n",k);
		double c = WB_weibull_c_param();
		printf("Weibull c param %f\n",c);
		printf("\n");

		wind_calculation();

		WB_height = 30.0f;
		WB_extrapolate_speed();
		wind_calculation();

	}
	//WB_Finalize();
	if(FD != NULL) fclose (stdout);
    return 0;
}

void wind_calculation() {
	/* HOURLY CALCULATIONS*/
	/*Calculate Hourly Average Wind Speed*/
	double avg_hourly_speed[24];
	WB_avg_hourly(&avg_hourly_speed[0],  wind_speed );
	/*Calculate Hourly Average Wind Power*/
	double avg_hourly_power[24];
	WB_avg_hourly(&avg_hourly_power[0],  wind_power );
	/*Calculate Hourly Lambert Persistance*/
	float lam_per_hourly[24];
	WB_lambert_persistance_hourly(&lam_per_hourly[0]);
	double *p_array_Ti=NULL;
	double *p_array_Wt=NULL;
	int SDC_array_length = WB_SDC(&p_array_Ti, &p_array_Wt);
	/*--------------------------------------------------------------------------------------------------------------------------------------------------------*/
	/* MONTLHLY CALCULATIONS*/
	/*Calculate the monthly Average Wind Speed*/
	double avg_monthly_speed[12];
	WB_avg_monthly(&avg_monthly_speed[0],wind_speed);
	/* Calculate Monthly Average wind speed in daytime and night time*/
	double avg_monthly_speed_day[12];
	double avg_monthly_speed_night[12];
	WB_avg_monthly_day_night(&avg_monthly_speed_day[0], &avg_monthly_speed_night[0], wind_speed);
	/*Calculate Monthly average power*/
	double avg_monthly_power[12];
	WB_avg_monthly(&avg_monthly_power[0],wind_power);
	/*Calculate monthly average win power in daytime and night*/
	double avg_monthly_power_day[12];
	double avg_monthly_power_night[12];
	WB_avg_monthly_day_night(&avg_monthly_power_day[0], &avg_monthly_power_night[0], wind_power);
	/* Variance, StandartDeviation, Weibull k and c parameters monthly*/
	double variance_monthly_arr[12];
	WB_variance_monthly(&variance_monthly_arr[0]);
	double sd_monthly_arr[12];
	WB_variance_to_sd(&variance_monthly_arr[0], &sd_monthly_arr[0],12);
	double k_param_monthly[12];
	WB_weibull_k_param_by_sd_and_avg(&sd_monthly_arr[0], &avg_monthly_speed[0], 12, &k_param_monthly[0]);
	double c_params_monthly[12];
	WB_weibull_c_param_monthly(&avg_monthly_speed[0], &k_param_monthly[0], 12, &c_params_monthly[0]);
	/*Calculate Monthly persistance values*/
	float lam_per_monthly[12];
	WB_lambert_persistance_monthly(&lam_per_monthly[0]);
	/*--------------------------------------------------------------------------------------------------------------------------------------------------------*/
	/*SEASONAL CALCULATIONS*/
	/*Calculate the Sesonal average wind speed*/
	double avg_sesonal_speed[4];
	WB_avg_seasonal(&avg_sesonal_speed[0], wind_speed);
	/*Calculate the Sesonal average win power*/
	double avg_sesonal_power[4];
	WB_avg_seasonal(&avg_sesonal_power[0], wind_power);
	/*Calculate the Sesonal Lambert persistance values*/
	float lam_per_seasonal[4];
	WB_lambert_persistance_seasonal(&lam_per_seasonal[0]);
	/*--------------------------------------------------------------------------------------------------------------------------------------------------------*/
	printf("Average Speed,Power and Lambert Persistance values (%g m.)\n",WB_height);
	printf("Hourly\t\t\t\t\t\tMonthly\t\t\t\t\tSesonal\n");
	printf("-----------------------------\t\t\t-----------------------------\t\t-----------------------------\n");
	printf("Hours\tSpeed\tPower\tLambert\t\t\tMonths\tSpeed\tPower\tLambert\t\tSeasons\tSpeed\tPower\tLambert\n");
	register int i;
	for(i=0;i<24;i++){
		printf("%d\t%g\t%g\t%e",(i+1), avg_hourly_speed[i], avg_hourly_power[i],lam_per_hourly[i]);
		if(i<12){
			printf("\t\t");
			printf("%d\t%g\t%g\t%e",(i+1), avg_monthly_speed[i], avg_monthly_power[i], lam_per_monthly[i]);
		}
		if(i<4){
			printf("\t");
			printf("%d\t%g\t%g\t%e",(i+1), avg_sesonal_speed[i], avg_sesonal_power[i], lam_per_seasonal[i]);
		}
		printf("\n");
	}
	printf("\n");
	printf("Monthly Average Speed and Power values on daytime and nighttime basis (%g m.)\n",WB_height);
	printf("Day-time\t\t\t\tNight-time\n");
	printf("-----------------------------\t\t-----------------------------\n");
	printf("Months\tSpeed\t\tPower\t\tMonths\tSpeed\t\tPower\n");
	for(i=0;i<12;i++){
		if(i<12){
			//printf("\t\t");
			printf("%d\t%e\t%e",(i+1), avg_monthly_speed_day[i], avg_monthly_power_day[i]);
			printf("\t%d\t%e\t%e",(i+1), avg_monthly_speed_night[i], avg_monthly_power_night[i]);
		}
		printf("\n");
	}
	printf("\n");
	printf("Monthly Weibull k and c parameters (%g m.)\n",WB_height);
	printf("----------------------------------------------------------\n");
	printf("Months\tVariance\tSD\t\tk\t\tc\n");
	for(i=0;i<12;i++){
		if(i<12){
			//printf("\t\t");
			printf("%d\t%e\t%e\t%e\t%e",(i+1), variance_monthly_arr[i], sd_monthly_arr[i], k_param_monthly[i], c_params_monthly[i]);
		}
		printf("\n");
	}
	printf("\n");
	printf("Speed Duration Curve Parameters (%g m.)\n",WB_height);
	printf("----------------------------------------------------------\n");
	printf("D\tTi\t\ti x delta_V(m/s)\t\t\n");
	for(i=0;i<SDC_array_length;i++){
			printf("%d\t%e\t%e",(i+1), p_array_Ti[i], p_array_Wt[i]);
			printf("\n");
	}
	if(p_array_Ti!=NULL) free(p_array_Ti);
	if(p_array_Wt!=NULL) free(p_array_Wt);
}
